package com.dins.elashutina.parser;

import java.util.Collection;
import java.util.Iterator;
import java.util.Stack;

/**
 * Created with IntelliJ IDEA.
 * User: ekaterina.lashutina
 * Date: 02.09.13
 * Time: 11:28
 */
public class Tree implements Collection<Node> {

    public enum Type {COBERTURA, BULLSEYE, JACOCO}

    private int size;
    private Node root;
    private Type type;

    public Tree(Type type) {

        this.type = type;
        size = 0;
        root = null;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean contains(Object o) {
        if (this.isEmpty()) {
            return false;
        } else {
            if (getRoot().getClass() != o.getClass()) {
                if (o.getClass() == String.class) {
                    for (Node n : this) {
                        if (n.getPath().equals(o)) return true;
                    }
                }
                return false;
            } else {
                for (Node n : this) {
                    if (n.equals(o) && (n.hashCode() == o.hashCode())) return true;
                }
                return false;
            }
        }

    }

    public Node getNode(String path) {
        if (this.isEmpty()) {
            return null;
        } else {
            for (Node n : this) {
                String st = n.getPath();
                if (path.equals(n.getPath())) {
                    n.setIterated(true);
                    return n;
                }
            }
            return null;
        }
    }

    public Iterator<Node> iterator() {
        return new Iterator<Node>() {
            Stack<Node> childrenStack = new Stack<Node>();
            Node node;
            int index = 0;


            @Override
            public boolean hasNext() {
                if (root.equals(null)) {
                    return false;
                }
                return index < size();
            }

            @Override
            public Node next() {
                if (node == null && index == 0) {
                    node = root;
                } else {
                    if (root.equals(null)) {
                        return null;
                    } else {
                        if (node.getChildren().size() != 0) {
                            for (Node n : node.getChildren()) {
                                childrenStack.push(n);
                            }
                        }
                        node = childrenStack.pop();
                    }
                }
                index++;
                return node;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Not supported yet");
            }

            public int getIndex() {
                return index;
            }
        };
    }

    @Override
    public Object[] toArray() {
        throw new UnsupportedOperationException("Not supported yet");
    }


    @Override
    public Object[] toArray(Object[] a) {
        throw new UnsupportedOperationException("Not supported yet");
    }

    public void setRoot(Node root) {
        this.root = root;
        size++;
    }

    @Override
    public boolean add(Node node) {
        if (this.isEmpty()) {
            root = node;
        } else {
            node.getParent().addChild(node);
        }
        size++;
        return true;
    }

//    public void add(String path) {
//        if (this.isEmpty()) {
//            root = new Node(path);
//        }
//        String[] tmp = path.split("\\\\");
//        String subPath = "";
//        for (int i = 0; i < tmp.length - 1; i++) {
//            if (tmp[i].equals("")) {
//                subPath += tmp[i];
//            } else {
//                subPath += "\\" + tmp[i];
//            }
//        }
//        if (contains(subPath)) {
//            Node n = new Node(path);
//            Node p = getNode(subPath);
//            p.addChild(n);
//            n.setParent(p);
//            size++;
//        } else {
//            if (path.equals(subPath)) {
//                this.setRoot(new Node(path));
//                size++;
//            }
//            add(subPath);
//            add(path);
//        }
//    }

    @Override
    public boolean remove(Object o) {
        throw new UnsupportedOperationException("Not supported yet");
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        if (this.isEmpty() || c.isEmpty()) {
            return false;
        }
        if (this.getClass() != c.getClass()) return false;
        else {
            if (this.size() != c.size()) return false;
            Iterator<?> i = c.iterator();
            while (i.hasNext()) {
                if (!this.contains(i.next())) return false;
            }
        }
        return true;
    }

    @Override
    public boolean addAll(Collection c) {
        throw new UnsupportedOperationException("Not supported yet");
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        throw new UnsupportedOperationException("Not supported yet");
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        throw new UnsupportedOperationException("Not supported yet");
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException("Not supported yet");
    }

    public Node getRoot() {
        return root;
    }

    public Type getType() {
        return type;
    }
}
